/*
 * Dispositivo.java
 *
 * Created on 2 de Abril de 2008, 01:27
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package Simulador.Hardware;

import Auxiliar.Fila;
import Simulador.Event.Evento;
import Simulador.Job.Segmento;

abstract public class Dispositivo implements DispositivoInterface {

    protected boolean ocupado = false;
    protected Fila fila;

    /**
     * Inicializa dispositivo.
     */
    public Dispositivo() {
        fila = new Fila();
        ocupado = false;
    }

    /**
     * TODO Verificar necessidade dos parametros.
     * @param tempoAtual
     * Momento Atual da Simulacao
     * @return
     * true caso o dispositivo esteja realizando uma operacao de IO. false caso
     * contrario.
     */
    protected boolean isBusy(float tempoAtual) {
        return ocupado;
    }

    /**
     * Comeca IO ou coloca o pedido na fila se o dispositivo estiver ocupado.
     * @param E 
     * Evento que causou a requisicao.
     * @return
     * Evento de Fim de IO.
     */
    public Evento requerirRecurso(Evento E) {
        if( E.getSegmento() == null){
            return null;
        }
        if (!isBusy(E.getMomentoDeChegada())) {
            Evento novo = new Evento(Evento.FimIODisco,
                    E.getSegmento(),
                    E.getMomentoDeChegada() + tempoTransacao(), E.getInfo());
            ocupado = true;
            return novo;
        } else {
            fila.addItem(E);
            return null;
        }
    }

    /**
     * Libera o recurso e, caso exista um processo na fila, realiza novo IO.
     * @param j
     * Processo que pediu o IO finalizado.
     * @param tempoAtual
     * Momento atual da simulacao.
     * @return
     * Novo evento, no caso da fila nao vazia.
     */
    public Evento liberarRecurso(Evento E) {
        Evento novo;
        ocupado = false;
        if (!fila.isEmpty()) {
            novo = requerirRecurso( (Evento)fila.getItem() );
        }else{
            novo = null;
        }
        return novo;
    }
    
    /*Implementar essa funcao para as classes Memoria e CPU ficarem mais simples.*/
    //abstract protected boolean executaTransacao()// tenta executar a transacao e caso o recurso
                                                 // esteja ocupado, retorna falso.
    
    /**
     * Calcula o tempo necessario para executar a transacao no dispositivo desejado.
     * @return
     * Tempo necessario para a transacao.
     */
    abstract protected float tempoTransacao();
}
